/**
 * COPYRIGHT HangZhou Trustway Technology Company Limited
 * All right reserved.
 */
package com.robam.cloud.common.util.alipay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayResponse;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.robam.cloud.common.bean.common.Constant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Map;

/**
 * @Description
 * @Author 薛铁琪
 * @CreateTime 2020-07-25 15:55
 * @Version 1.0
 */
@Slf4j
@Component
public class AlipayUtil {
    private final static String GATEWAYURL = "https://openapi.alipay.com/gateway.do";
    private final static String ERROR_ZFB_GATEWAY_FAILED = "error.zfb.platform.failed";
    private final static String GRANT_TYPE_BY_AUTHCODE = "authorization_code";    //通过authcode方式获取access token
    public static final String API_ENCODING_UTF_8 = "UTF-8";
    public static final String API_CONTENT_FORMAT = "json";
    public static final String API_SIGN_TYPE = "RSA2";
    private final static String LJKJ = "LJKJ";
    private final static String PASS = "T";


    public AlipayUser getAlipayUser(String authCode, String appId, String privateKey, String publicKey) {
        DefaultAlipayClient client = new DefaultAlipayClient(GATEWAYURL, appId, privateKey, API_CONTENT_FORMAT, API_ENCODING_UTF_8, publicKey, API_SIGN_TYPE);
        if (StringUtils.isEmpty(authCode)) {
            return null;
        }
        String accessToken = getAccessToken(authCode, client);
        if (StringUtils.isEmpty(accessToken)) {
            return null;
        }
        return getAlipayUserInfo(accessToken, client);
    }

    private String getAccessToken(String authCode, DefaultAlipayClient client) {
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode(authCode);
        request.setGrantType(GRANT_TYPE_BY_AUTHCODE);
        AlipaySystemOauthTokenResponse response;
        try {
            response = client.execute(request);
            return getAccessToken(response);
        } catch (AlipayApiException e) {
            log.error("event=" + ERROR_ZFB_GATEWAY_FAILED, e);
            return null;
        }
    }

    /**
     * 获取用户信息
     *
     * @param accessToken
     * @return
     */
    private AlipayUser getAlipayUserInfo(String accessToken, DefaultAlipayClient client) {
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response;
        try {
            response = client.execute(request, accessToken);
            return getUserInfoFromResponse(response);
        } catch (AlipayApiException e) {
            log.error("event=" + ERROR_ZFB_GATEWAY_FAILED, e);
            return null;
        }
    }

    private String getAccessToken(AlipaySystemOauthTokenResponse response) {
        if (response.isSuccess()) {
            return response.getAccessToken();
        }
        logFailedInfo(response);
        return null;
    }

    private void logFailedInfo(AlipayResponse response) {
        if (log.isInfoEnabled()) {
            StringBuilder sb = new StringBuilder()
                    .append("event=").append(ERROR_ZFB_GATEWAY_FAILED)
                    .append(" code=").append(response.getCode())
                    .append(" msg=").append(response.getMsg())
                    .append(" subCode=").append(response.getSubCode())
                    .append(" subMsg=").append(response.getSubMsg());
            for (Map.Entry<String, String> param : response.getParams().entrySet()) {
                sb.append(" ").append(param.getKey()).append("=").append(param.getValue());
            }
            log.debug(sb.toString());
        }
    }

    private AlipayUser getUserInfoFromResponse(AlipayUserInfoShareResponse response) {
        if (response.isSuccess()) {
            if (log.isDebugEnabled()) {
                String certNo = response.getCertNo();
                if (certNo != null && certNo.length() > 6) {
                    certNo = certNo.substring(0, certNo.length() - 6);
                }
                log.debug("userid={} username={} gender={} nickname={} certtype={} certno={} iscertified={} avatar={} mobile={}",
                        response.getUserId(), response.getUserName(), response.getGender(), response.getNickName(),
                        response.getCertType(), certNo, response.getIsCertified(), response.getAvatar(),
                        response.getMobile());
            }
            AlipayUser alipayUser = new AlipayUser();
            alipayUser.setUserId(response.getUserId());
            alipayUser.setGender(response.getGender());
            alipayUser.setNickName(response.getNickName());
            alipayUser.setAvatar(response.getAvatar());
            alipayUser.setMobile(response.getMobile());
            alipayUser.setProvince(response.getProvince());
            alipayUser.setCity(response.getCity());
            alipayUser.setAddress(response.getAddress());
            alipayUser.setUserType(response.getUserType());
            alipayUser.setUserStatus(response.getUserStatus());
            alipayUser.setCertType(response.getCertType());
            alipayUser.setCertNo(response.getCertNo());
            alipayUser.setIsCertificatied(response.getIsCertified());
            alipayUser.setUserName(response.getUserName());
            return alipayUser;
        }
        logFailedInfo(response);
        return null;
    }

    public String getCertifyId(String xm, String sfzmhm, String sfbr, String appId, String privateKey, String publicKey) {
        DefaultAlipayClient client = new DefaultAlipayClient(GATEWAYURL, appId, privateKey, API_CONTENT_FORMAT, API_ENCODING_UTF_8, publicKey, API_SIGN_TYPE);
        AlipayUserCertifyOpenInitializeRequest request = new AlipayUserCertifyOpenInitializeRequest();

        //构造身份信息json对象
        JSONObject identityObj = new JSONObject();
        //身份类型，必填，详细取值范围请参考接口文档说明
        if (Constant.SELF.equals(sfbr)) {
            identityObj.put("identity_type", "CERT_INFO");
        } else {
            identityObj.put("identity_type", "AGENT_CERT_INFO");
        }
        //证件类型，必填，详细取值范围请参考接口文档说明
        identityObj.put("cert_type", "IDENTITY_CARD");
        //真实姓名，必填
        identityObj.put("cert_name", xm);
        //证件号码，必填
        identityObj.put("cert_no", sfzmhm);

        //构造商户配置json对象
        JSONObject merchantConfigObj = new JSONObject();
        // 设置回调地址,必填. 如果需要直接在支付宝APP里面打开回调地址使用alipay协议，参考下面的案例：appId用固定值 20000067，url替换为urlEncode后的业务回跳地址
        // alipays://platformapi/startapp?appId=20000067&url=https%3A%2F%2Fapp.cqkqinfo.com%2Fcertify%2FzmxyBackNew.do
        merchantConfigObj.put("return_url", "alipays://platformapi/startapp?appId=20000067&url=https%3A%2F%2Fapp.cqkqinfo.com%2Fcertify%2FzmxyBackNew.do");

        //构造身份认证初始化服务业务参数数据
        JSONObject bizContentObj = new JSONObject();
        //商户请求的唯一标识，推荐为uuid，必填
        String orderNo = getOrderNum();
        bizContentObj.put("outer_order_no", orderNo);
        bizContentObj.put("biz_code", "FACE");
        bizContentObj.put("identity_param", identityObj);
        bizContentObj.put("merchant_config", merchantConfigObj);
        request.setBizContent(bizContentObj.toString());
        //发起请求
        AlipayUserCertifyOpenInitializeResponse response = null;
        try {
            response = client.execute(request);
            if (response.isSuccess()) {
                log.debug("调用成功");
                //接口调用成功，从返回对象中获取certify_id
                String certifyId = response.getCertifyId();
                //执行后续流程...
                return certifyId;
            } else {

                logFailedInfo(response);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getCertifyUrl(String certifyId, String appId, String privateKey, String publicKey) {
        DefaultAlipayClient client = new DefaultAlipayClient(GATEWAYURL, appId, privateKey, API_CONTENT_FORMAT, API_ENCODING_UTF_8, publicKey, API_SIGN_TYPE);
        //获取alipay client
        //AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, "json", CHARSET, ALIPAY_PUBLIC_KEY, "RSA2");
        AlipayUserCertifyOpenCertifyRequest request = new AlipayUserCertifyOpenCertifyRequest();

        //设置certifyId
        JSONObject bizContentObj = new JSONObject();
        bizContentObj.put("certify_id", certifyId);
        request.setBizContent(bizContentObj.toString());

        //生成请求链接，这里一定要使用GET模式
        AlipayUserCertifyOpenCertifyResponse response = null;
        try {
            response = client.pageExecute(request, "GET");
            if (response.isSuccess()) {
                log.debug("开始认证服务调用成功");
                String certifyUrl = response.getBody();
                //执行后续流程...
                return certifyUrl;
            } else {
                log.debug("调用失败");
                logFailedInfo(response);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }


    public String certifyQuery(String certifyId, String appId, String privateKey, String publicKey) {
        DefaultAlipayClient client = new DefaultAlipayClient(GATEWAYURL, appId, privateKey, API_CONTENT_FORMAT, API_ENCODING_UTF_8, publicKey, API_SIGN_TYPE);
        AlipayUserCertifyOpenQueryRequest request = new AlipayUserCertifyOpenQueryRequest();
        //构造身份认证初始化服务业务参数数据
        JSONObject bizContentObj = new JSONObject();
        bizContentObj.put("certify_id", certifyId);
        request.setBizContent(bizContentObj.toString());
        AlipayUserCertifyOpenQueryResponse response = null;
        try {
            response = client.execute(request);
            if (response.isSuccess()) {
                log.debug("调用成功");
                String body = response.getBody();
                String materialInfo = response.getMaterialInfo();
                if (StringUtils.isNotEmpty(body)) {
                    JSONObject jsonObject = JSON.parseObject(body);
                    JSONObject jsonObject1 = jsonObject.getJSONObject("alipay_user_certify_open_query_response");
                    String passed = jsonObject1.getString("passed");
                    if (PASS.equals(passed)) {
                        JSONObject jsonObject3 = JSON.parseObject(jsonObject1.getString("material_info"));
                        JSONObject jsonObject4 = jsonObject3.getJSONObject("facial_picture_front");
                        String base64 = jsonObject4.getString("FEATURE_FACE");
                        return base64;
                    }
                }
            } else {
                logFailedInfo(response);
                log.debug("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getOrderNum() {
        String orderNo = "";
        Calendar now = Calendar.getInstance();
        String year = now.get(Calendar.YEAR) + "";
        int intMonth = now.get(Calendar.MONTH) + 1;
        int intDay = now.get(Calendar.DAY_OF_MONTH);
        String month = "";
        String day = "";
        if (intMonth < 10) {
            month = "0" + intMonth;
        } else {
            month = intMonth + "";
        }
        if (intDay < 10) {
            day = "0" + intDay;
        } else {
            day = intDay + "";
        }
        long now1 = System.currentTimeMillis();
        int ran = (int) ((Math.random() * 9 + 1) * 1000000);
        orderNo = orderNo + LJKJ + year + month + day + now1 + ran;
        return orderNo;
    }
}
